Saturday, March 18, 2006

Swing Tab order

I've been having a problem using custom focus traversal policies. Basically, I have a frame with some components, one of which is a panel that contains other components. I want to use the frames focus traversal policy to tab through it's components, until it reaches the panel. At that point, I would like the panel to be able to control its own focus cycle. Once the last component in the panel is reached, I would like the next component that receives focus to be the component designated to follow the panel by the frames focus traversal policy. I've searched this forum and found lots of similiar problems spread throughout many threads. Here's one solution I came up with...

import javax.swing.*;
import java.awt.*;

public class focusExample extends JFrame {
protected JTextField tf1, tf2, tf3, tf4, tf5, tf6;
protected MyPanel panel;
protected MyFocusTraversalPolicy focusTraversalPolicy;

public focusExample() {
tf1 = new JTextField(10);
tf2 = new JTextField(10);
tf3 = new JTextField(10);
tf4 = new JTextField(10);
tf5 = new JTextField(10);
tf6 = new JTextField(10);
panel = new MyPanel();

getContentPane().setLayout(new FlowLayout());

this.getContentPane().add(tf1);
this.getContentPane().add(tf2);
this.getContentPane().add(tf3);
this.getContentPane().add(panel);
this.getContentPane().add(tf4);
this.getContentPane().add(tf5);
this.getContentPane().add(tf6);

focusTraversalPolicy = new MyFocusTraversalPolicy();
setFocusTraversalPolicy(focusTraversalPolicy);

pack();
setVisible(true);
}

public class MyFocusTraversalPolicy extends FocusTraversalPolicy {
public Component getComponentAfter(Container focusCycleRoot, Component aComponent) {
if(aComponent.equals(tf1)) return tf2;
else if(aComponent.equals(tf2)) return tf3;
else if(aComponent.equals(tf3)) return panel.getFocusTraversalPolicy().getDefaultComponent(panel);
else if(panel.isAncestorOf(aComponent)){
if(aComponent.equals(panel.getFocusTraversalPolicy().getLastComponent(panel))) return tf4;
else return panel.getFocusTraversalPolicy().getComponentAfter(panel, aComponent);
}
else if(aComponent.equals(tf4)) return tf5;
else if(aComponent.equals(tf5)) return tf6;
else return tf1;
}

public Component getComponentBefore(Container focusCycleRoot, Component aComponent) {
if(aComponent.equals(tf6)) return tf5;
else if(aComponent.equals(tf5)) return tf4;
else if(aComponent.equals(tf4)) return panel.getFocusTraversalPolicy().getLastComponent(panel);
else if(panel.isAncestorOf(aComponent)){
if(aComponent.equals(panel.getFocusTraversalPolicy().getFirstComponent(panel))) return tf3;
else return panel.getFocusTraversalPolicy().getComponentBefore(panel, aComponent);
}
else if(aComponent.equals(tf3)) return tf2;
else if(aComponent.equals(tf2)) return tf1;
else return tf6;
}

public Component getDefaultComponent(Container focusCycleRoot) {
return tf1;
}

public Component getFirstComponent(Container focusCycleRoot) {
return tf1;
}

public Component getLastComponent(Container focusCycleRoot) {
return tf6;
}
}

public class MyPanel extends JPanel {
protected JTextField tf1, tf2, tf3;
protected FocusTraversalPolicy focusTraversalPolicy;

public MyPanel() {
tf1 = new JTextField(10);
tf2 = new JTextField(10);
tf3 = new JTextField(10);

this.add(tf3);
this.add(tf2);
this.add(tf1);

focusTraversalPolicy = new FocusTraversalPolicy() {
public Component getComponentAfter(Container focusCycleRoot, Component aComponent) {
if(aComponent.equals(tf1)) return tf2;
else if(aComponent.equals(tf2)) return tf3;
else return tf1;
}

public Component getComponentBefore(Container focusCycleRoot, Component aComponent) {
if(aComponent.equals(tf3)) return tf2;
else if(aComponent.equals(tf2)) return tf1;
else return tf3;
}

public Component getDefaultComponent(Container focusCycleRoot) {
return tf1;
}

public Component getFirstComponent(Container focusCycleRoot) {
return tf1;
}

public Component getLastComponent(Container focusCycleRoot) {
return tf3;
}
};
}

public FocusTraversalPolicy getFocusTraversalPolicy() {
return focusTraversalPolicy;
}
}

public static void main(String args[]) {
new focusExample();
}
}


This also works if MyPanel is defined in another file. By default, Container's getFocusTraversalPolicy() will return null if a call to isFocusCycleRoot() on the container returns false. In MyPanel, getFocusTraversalPolicy() is overridden to return the focus traversal policy even if the panel is not a focus cycle root. This allows the frame the panel is on access to the panel's focus traversal policy. You should over-ride getFocusTraversalPolicy() in any subclasses of container that you add to your frame, or you'll get a null-pointer exception when calling panel.getFocusTraversalPolicy(). I'm unsure about any side effects from over-ridding getFocusTraversalPolicy(); if anyone knows of any problems this may cause, please lte me know.

6 comments:

Anonymous said...

Really its so useful coding part to me..Good effort keep it up..
best dissertation writing

Saro said...

Great Article… I love to read your articles because your writing style is too good, its is very very helpful for all of us and I never get bored while reading your article because, they are becomes a more and more interesting from the starting lines until the end.

rpa training in bangalore
best rpa training in bangalore
RPA training in bangalore
RPA courses in bangalore

Unknown said...

Great content thanks for sharing this informative blog which provided me technical information keep posting.
python Online training in chennai
python Online training in bangalore
python interview question and answers

pratheep said...

Really it was an awesome article about JAVA, very interesting to read.You have provided an nice article,Thanks for sharing.
Java training in chennai | Java training in annanagar | Java training in omr | Java training in porur | Java training in tambaram | Java training in velachery

Anu said...

I know, it is not an easy task to write such a big article in one day, I've tried that and I've failed. But, here you are, trying the big task and finishing it off and getting good comments
and ratings. That is one hell of a job done!
devops training in chennai | devops training in anna nagar | devops training in omr | devops training in porur | devops training in tambaram | devops training in velachery

Revathi said...

Java tips really very good information share ta all of us..i cant except you make great post and great job...thanks for your information..keep share!!!

Android Training in Chennai

Android Online Training in Chennai

Android Training in Bangalore

Android Training in Hyderabad

Android Training in Coimbatore

Android Training

Android Online Training